package org.aceor.mddal.gateway.resultset;

import com.google.common.collect.Lists;
import org.aceor.mddal.common.sqlparser.result.context.MergeContext;
import org.aceor.mddal.common.sqlparser.result.object.OrderByColumn;
import org.aceor.mddal.gateway.merger.orderby.OrderByValue;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * Created by lxue on 16/4/16.
 */
public class OrderByResultSet extends BaseResultSet implements ResultSet {

    private List<OrderByColumn> orderByColumns;
    private final List<ResultSet> effectiveResultSets;
    private volatile boolean inited;

    public OrderByResultSet(List<ResultSet> resultSets, MergeContext mergeContext) {
        super(resultSets, mergeContext.getLimit());
        effectiveResultSets = Lists.newArrayList();
        orderByColumns = mergeContext.getOrderByColumns();
    }

    @Override
    protected boolean nextRowSet() throws SQLException {
        if (!inited) {
            //effectiveResultSets中放入所有Resultset,每个rs调用next(),即准备好取值
            initialEffectiveResultSets();
        } else {
            //一个排序的结果被取出.然后继续调用该结果集的next(),让取值做好准备.如果该结果集没有可取值时,remove掉
            nextEffectiveResultSets();
        }
        OrderByValue choosenOrderByValue = null;
        for (ResultSet each : effectiveResultSets) {
            OrderByValue eachOrderByValue = new OrderByValue(orderByColumns, each);
            if (null == choosenOrderByValue || choosenOrderByValue.compareTo(eachOrderByValue) > 0) {
                choosenOrderByValue = eachOrderByValue;
                setCurrentResultSet(each);
            }
        }
        return !effectiveResultSets.isEmpty();
    }

    private void initialEffectiveResultSets() throws SQLException {
        for (ResultSet each : getResultSets()) {
            if (each.next()) {
                effectiveResultSets.add(each);
            }
        }
        inited = true;
    }

    private void nextEffectiveResultSets() throws SQLException {
        boolean next = getCurrentResultSet().next();
        if (!next) {
            effectiveResultSets.remove(getCurrentResultSet());
        }
    }
}
